/**********************************************
 * 
 * File Name				:	ProcessAdminLogonAction.java
 * 
 * Last Changed Date		: 	$Date: 2009-08-01 11:12:53 +0800 (星期六, 01 八月 2009) $
 * 
 * Last Changed Revision	:	$Revision: 86 $
 * 
 * Last Changed Author		:	$Author: cfanboy $
 * 
 * File Header URL			:	$HeadURL: svn://www.svnhost.cn/Busi-Building/code/branch/src/com/busibuilding/administrate/security/action/ProcessAdminLogonAction.java $
 * 
 * ********************************************
 */

package com.busibuilding.administrate.security.action;

import java.util.ArrayList;
import java.util.List;

import org.apache.axis.utils.StringUtils;
import org.apache.log4j.Logger;

import com.busibuilding.administrate.security.services.SysLogInfoService;
import com.busibuilding.administrate.security.services.UserManagementService;
import com.busibuilding.administrate.security.vo.LogInfoCVO;
import com.busibuilding.administrate.security.vo.UserCVO;
import com.busibuilding.common.action.CommonActionImpl;
import com.busibuilding.common.config.sqlmap.entities.MenuVO;
import com.busibuilding.parameters.services.ParametersService;
import com.busibuilding.utils.DateUtils;
import com.busibuilding.utils.MD5Util;


/**
 * Class Name: ProcessAdminLogonAction.java
 * Description: 
 * @author YU Zhipeng
 * @version 1.0
 * @since 1.0
 * Date: 2009-7-10
 */

public class ProcessAdminLogonAction extends CommonActionImpl{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1947811732746275013L;

	private static Logger logger = Logger.getLogger(ProcessAdminLogonAction.class);
	
	private UserManagementService userMgmtService;
	private SysLogInfoService logService;
	private ParametersService paramService;
	
	public void setUserMgmtService(UserManagementService userMgmtService) {
		this.userMgmtService = userMgmtService;
	}

	public void setLogService(SysLogInfoService logService) {
		this.logService = logService;
	}

	public void setParamService(ParametersService paramService) {
		this.paramService = paramService;
	}

	public String input() throws Exception{
		return INPUT;
	}
	
	/**
	 * Process Administrator login
	 * @return
	 * @throws Exception
	 */
	public String processLogon() throws Exception{
		UserCVO userCvo = new UserCVO();
		userCvo.setUserName(getUserName());
		List<UserCVO> list = userMgmtService.searchUserByCondition(userCvo);
		if (list.size() == 0){
			addActionError(getText("error.admin.loginPage.userError"));
			return INPUT;
		}else if (list.size() > 0){
			// Only for get the multi-usergroup
			List<String> groupBelongToUser = new ArrayList<String>();
			
			for (UserCVO admin : list){
				groupBelongToUser.add(admin.getUserGroupCode());
			}
			
			UserCVO admin = list.get(0);
			
			String value = paramService.getParamValue(CONST_LOGON_FAILURE_TIMES_CODE, CONST_SECURITY_CATEGORY);
			
			if (YES.equals(admin.getDefunctInd())){
				String failureReason = getText("error.admin.loginPage.userDefuncted"); 
				addActionError(failureReason);
				logSystemLog(admin.getUserId(), NO, failureReason);
				return INPUT;
			}else if (admin.getFailureLogonTimes() > Integer.parseInt(value)){
				String failureReason = getText("error.admin.loginPage.failureLogonTimes", new String[]{value});
				addActionError(failureReason);
				logSystemLog(admin.getUserId(), NO, failureReason);
				return INPUT;
			}else if (YES.equals(admin.getLockedInd())){
				String failureReason = getText("error.admin.loginPage.userLocked");
				addActionError(failureReason);
				logSystemLog(admin.getUserId(), NO, failureReason);
				return INPUT;
			}else if (!MD5Util.md5(getPassword()).equals(admin.getEnPassword())){
				String failureReason = getText("error.admin.loginPage.passwordError");
				addActionError(failureReason);
				logSystemLog(admin.getUserId(), NO, failureReason);
//				Update the FAILURE_LOGON_TIMES
				UserCVO cvo = new UserCVO();
				cvo.setUserId(admin.getUserId());
				cvo.setVersion(admin.getVersion());
				cvo.setFailureLogonTimes(admin.getFailureLogonTimes() + 1);
				cvo.setLastUpdatedBy(admin.getUserId());
				cvo.setLastUpdatedDate(DateUtils.getCurrentTimestamp());
//				If failure logon times more than system setting, then update the LOCKED_IND to Y
				if (admin.getFailureLogonTimes() + 1 > Integer.parseInt(value)){
					cvo.setLockedInd(YES);
				}
				userMgmtService.updateUser(cvo);	
				
				return INPUT;
			}else{
				int logId = logSystemLog(admin.getUserId(), YES, null);
				admin.setSystemLogId(logId);
				admin.setLastLogonDateTimeForDisplay(DateUtils.toString(admin.getLastSuccessLogonDate(), DATA_TIME_PATTERN));
//				Update the last_success_logon_time
				UserCVO cvo = new UserCVO();
				cvo.setUserId(admin.getUserId());
				cvo.setVersion(admin.getVersion());
				cvo.setLastSuccessLogonDate(DateUtils.getCurrentTimestamp());
				cvo.setLastUpdatedBy(admin.getUserId());
				cvo.setLastUpdatedDate(DateUtils.getCurrentTimestamp());
				cvo.setFailureLogonTimes(ZERO_TIMES);
				userMgmtService.updateUser(cvo);
				
				admin.setGroupBelongToUser(groupBelongToUser);
				
				setSessionAttribute(SESSION_LOGON_ADMIN_USER, admin);
				
				String menuBar = genericMenuBar(getUserName());
				
				setSessionAttribute(SYSTEM_MENU, menuBar);
			}
		}	
		
		return SUCCESS;
	}
	
	private String genericMenuBar(String loginName) throws Exception{
		StringBuffer bar = new StringBuffer("<div id=\"menu\">");
		bar.append("<ul class=\"menu\" style=\"width: 100%;\">");
		
		UserCVO folderParam = new UserCVO();
		folderParam.setUserName(loginName);
		folderParam.setMenuType(MENU_TYPE_FOLDER);
		
		List<MenuVO> parentMenuList = userMgmtService.getBelongToUserMenus(folderParam);
		if (parentMenuList != null && parentMenuList.size() > 0){
			for (MenuVO pMenu : parentMenuList){
				String menuId = pMenu.getMenuId().toString();				
				bar.append("<li><a href=\"#\" class=\"parent\"><span>").append(pMenu.getMenuName()).append("</span></a>");
				
				// Get the menu item that belongs to current parent menu
				UserCVO itemParam = new UserCVO();
				itemParam.setUserName(loginName);
				itemParam.setMenuType(MENU_TYPE_ITEM);
				itemParam.setParentMenuId(menuId);
				List<MenuVO> itemMenuList = userMgmtService.getBelongToUserMenus(itemParam);
				if (itemMenuList != null && itemMenuList.size() > 0){
					bar.append("<div><ul>");
					for (MenuVO iMenu : itemMenuList){						
						bar.append("<li><a href=\"")
						   .append(StringUtils.isEmpty(iMenu.getMenuUrl()) ? "#" : iMenu.getMenuUrl())
						   .append("\"><span>").append(iMenu.getMenuName()).append("</span></a></li>");
					}					
					bar.append("</ul></div>");
				}
				bar.append("</li>");
			}			
		}
		
		bar.append("</ul></div>");		
		logger.debug(">>>>> Menu Bar Codes: " + bar.toString());
		
		return bar.toString();
	}
	
	/**
	 * Process Administrator Log out
	 * @return
	 * @throws Exception
	 */
	public String processLogout() throws Exception{
		UserCVO logonAdmin = (getSessionAttribute(SESSION_LOGON_ADMIN_USER) instanceof UserCVO) ? ((UserCVO)getSessionAttribute(SESSION_LOGON_ADMIN_USER)) : null;
		if (logonAdmin != null){
			LogInfoCVO logCvo = new LogInfoCVO();
			logCvo.setLogId(logonAdmin.getSystemLogId());
			logCvo.setLogoffDateTime(DateUtils.getCurrentTimestamp());
			logService.updateSysteLog(logCvo);
		}
		
		getSession().invalidate();
		return INPUT;
	}
	
	/**
	 * Log the log
	 * @param userId
	 * @return
	 * @throws Exception
	 */
	private int logSystemLog(int userId, String isSucceed, String failureReason) throws Exception{
		LogInfoCVO logCvo = new LogInfoCVO();
		logCvo.setLogonDateTime(DateUtils.getCurrentTimestamp());
		logCvo.setLogonUserId(userId);
		logCvo.setLogonIpAddr(getRequest().getRemoteAddr());
		logCvo.setSuccessInd(isSucceed);
		logCvo.setFailureReason(failureReason == null ? null : failureReason);
		return logService.logSystemLog(logCvo);
	}
	
	private String userName;
	private String password;

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}
	
}
